home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / parisc / include / asm / floppy.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  6.6 KB  |  272 lines

  1. /*    Architecture specific parts of the Floppy driver
  2.  *
  3.  *    Linux/PA-RISC Project (http://www.parisc-linux.org/)
  4.  *    Copyright (C) 2000 Matthew Wilcox (willy a debian . org)
  5.  *    Copyright (C) 2000 Dave Kennedy
  6.  *
  7.  *    This program is free software; you can redistribute it and/or modify
  8.  *    it under the terms of the GNU General Public License as published by
  9.  *    the Free Software Foundation; either version 2 of the License, or
  10.  *    (at your option) any later version.
  11.  *
  12.  *    This program is distributed in the hope that it will be useful,
  13.  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *    GNU General Public License for more details.
  16.  *
  17.  *    You should have received a copy of the GNU General Public License
  18.  *    along with this program; if not, write to the Free Software
  19.  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20.  */
  21. #ifndef __ASM_PARISC_FLOPPY_H
  22. #define __ASM_PARISC_FLOPPY_H
  23.  
  24. #include <linux/vmalloc.h>
  25.  
  26.  
  27. /*
  28.  * The DMA channel used by the floppy controller cannot access data at
  29.  * addresses >= 16MB
  30.  *
  31.  * Went back to the 1MB limit, as some people had problems with the floppy
  32.  * driver otherwise. It doesn't matter much for performance anyway, as most
  33.  * floppy accesses go through the track buffer.
  34.  */
  35. #define _CROSS_64KB(a,s,vdma) \
  36. (!vdma && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
  37.  
  38. #define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1)
  39.  
  40.  
  41. #define SW fd_routine[use_virtual_dma&1]
  42. #define CSW fd_routine[can_use_virtual_dma & 1]
  43.  
  44.  
  45. #define fd_inb(port)            readb(port)
  46. #define fd_outb(value, port)        writeb(value, port)
  47.  
  48. #define fd_request_dma()        CSW._request_dma(FLOPPY_DMA,"floppy")
  49. #define fd_free_dma()           CSW._free_dma(FLOPPY_DMA)
  50. #define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
  51. #define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
  52. #define fd_free_irq()        free_irq(FLOPPY_IRQ, NULL)
  53. #define fd_get_dma_residue()    SW._get_dma_residue(FLOPPY_DMA)
  54. #define fd_dma_mem_alloc(size)    SW._dma_mem_alloc(size)
  55. #define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io)
  56.  
  57. #define FLOPPY_CAN_FALLBACK_ON_NODMA
  58.  
  59. static int virtual_dma_count=0;
  60. static int virtual_dma_residue=0;
  61. static char *virtual_dma_addr=0;
  62. static int virtual_dma_mode=0;
  63. static int doing_pdma=0;
  64.  
  65. static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
  66. {
  67.     register unsigned char st;
  68.  
  69. #undef TRACE_FLPY_INT
  70.  
  71. #ifdef TRACE_FLPY_INT
  72.     static int calls=0;
  73.     static int bytes=0;
  74.     static int dma_wait=0;
  75. #endif
  76.     if (!doing_pdma) {
  77.         floppy_interrupt(irq, dev_id, regs);
  78.         return;
  79.     }
  80.  
  81. #ifdef TRACE_FLPY_INT
  82.     if(!calls)
  83.         bytes = virtual_dma_count;
  84. #endif
  85.  
  86.     {
  87.         register int lcount;
  88.         register char *lptr = virtual_dma_addr;
  89.  
  90.         for (lcount = virtual_dma_count; lcount; lcount--) {
  91.             st = fd_inb(virtual_dma_port+4) & 0xa0 ;
  92.             if (st != 0xa0) 
  93.                 break;
  94.             if (virtual_dma_mode) {
  95.                 fd_outb(*lptr, virtual_dma_port+5);
  96.             } else {
  97.                 *lptr = fd_inb(virtual_dma_port+5);
  98.             }
  99.             lptr++;
  100.         }
  101.         virtual_dma_count = lcount;
  102.         virtual_dma_addr = lptr;
  103.         st = fd_inb(virtual_dma_port+4);
  104.     }
  105.  
  106. #ifdef TRACE_FLPY_INT
  107.     calls++;
  108. #endif
  109.     if (st == 0x20)
  110.         return;
  111.     if (!(st & 0x20)) {
  112.         virtual_dma_residue += virtual_dma_count;
  113.         virtual_dma_count = 0;
  114. #ifdef TRACE_FLPY_INT
  115.         printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", 
  116.                virtual_dma_count, virtual_dma_residue, calls, bytes,
  117.                dma_wait);
  118.         calls = 0;
  119.         dma_wait=0;
  120. #endif
  121.         doing_pdma = 0;
  122.         floppy_interrupt(irq, dev_id, regs);
  123.         return;
  124.     }
  125. #ifdef TRACE_FLPY_INT
  126.     if (!virtual_dma_count)
  127.         dma_wait++;
  128. #endif
  129. }
  130.  
  131. static void fd_disable_dma(void)
  132. {
  133.     if(! (can_use_virtual_dma & 1))
  134.         disable_dma(FLOPPY_DMA);
  135.     doing_pdma = 0;
  136.     virtual_dma_residue += virtual_dma_count;
  137.     virtual_dma_count=0;
  138. }
  139.  
  140. static int vdma_request_dma(unsigned int dmanr, const char * device_id)
  141. {
  142.     return 0;
  143. }
  144.  
  145. static void vdma_nop(unsigned int dummy)
  146. {
  147. }
  148.  
  149.  
  150. static int vdma_get_dma_residue(unsigned int dummy)
  151. {
  152.     return virtual_dma_count + virtual_dma_residue;
  153. }
  154.  
  155.  
  156. static int fd_request_irq(void)
  157. {
  158.     if(can_use_virtual_dma)
  159.         return request_irq(FLOPPY_IRQ, floppy_hardint,
  160.                    IRQF_DISABLED, "floppy", NULL);
  161.     else
  162.         return request_irq(FLOPPY_IRQ, floppy_interrupt,
  163.                    IRQF_DISABLED, "floppy", NULL);
  164. }
  165.  
  166. static unsigned long dma_mem_alloc(unsigned long size)
  167. {
  168.     return __get_dma_pages(GFP_KERNEL, get_order(size));
  169. }
  170.  
  171.  
  172. static unsigned long vdma_mem_alloc(unsigned long size)
  173. {
  174.     return (unsigned long) vmalloc(size);
  175.  
  176. }
  177.  
  178. #define nodma_mem_alloc(size) vdma_mem_alloc(size)
  179.  
  180. static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
  181. {
  182.     if((unsigned int) addr >= (unsigned int) high_memory)
  183.         return vfree((void *)addr);
  184.     else
  185.         free_pages(addr, get_order(size));        
  186. }
  187.  
  188. #define fd_dma_mem_free(addr, size)  _fd_dma_mem_free(addr, size) 
  189.  
  190. static void _fd_chose_dma_mode(char *addr, unsigned long size)
  191. {
  192.     if(can_use_virtual_dma == 2) {
  193.         if((unsigned int) addr >= (unsigned int) high_memory ||
  194.            virt_to_bus(addr) >= 0x1000000 ||
  195.            _CROSS_64KB(addr, size, 0))
  196.             use_virtual_dma = 1;
  197.         else
  198.             use_virtual_dma = 0;
  199.     } else {
  200.         use_virtual_dma = can_use_virtual_dma & 1;
  201.     }
  202. }
  203.  
  204. #define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size)
  205.  
  206.  
  207. static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
  208. {
  209.     doing_pdma = 1;
  210.     virtual_dma_port = io;
  211.     virtual_dma_mode = (mode  == DMA_MODE_WRITE);
  212.     virtual_dma_addr = addr;
  213.     virtual_dma_count = size;
  214.     virtual_dma_residue = 0;
  215.     return 0;
  216. }
  217.  
  218. static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
  219. {
  220. #ifdef FLOPPY_SANITY_CHECK
  221.     if (CROSS_64KB(addr, size)) {
  222.         printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size);
  223.         return -1;
  224.     }
  225. #endif
  226.     /* actual, physical DMA */
  227.     doing_pdma = 0;
  228.     clear_dma_ff(FLOPPY_DMA);
  229.     set_dma_mode(FLOPPY_DMA,mode);
  230.     set_dma_addr(FLOPPY_DMA,virt_to_bus(addr));
  231.     set_dma_count(FLOPPY_DMA,size);
  232.     enable_dma(FLOPPY_DMA);
  233.     return 0;
  234. }
  235.  
  236. static struct fd_routine_l {
  237.     int (*_request_dma)(unsigned int dmanr, const char * device_id);
  238.     void (*_free_dma)(unsigned int dmanr);
  239.     int (*_get_dma_residue)(unsigned int dummy);
  240.     unsigned long (*_dma_mem_alloc) (unsigned long size);
  241.     int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
  242. } fd_routine[] = {
  243.     {
  244.         request_dma,
  245.         free_dma,
  246.         get_dma_residue,
  247.         dma_mem_alloc,
  248.         hard_dma_setup
  249.     },
  250.     {
  251.         vdma_request_dma,
  252.         vdma_nop,
  253.         vdma_get_dma_residue,
  254.         vdma_mem_alloc,
  255.         vdma_dma_setup
  256.     }
  257. };
  258.  
  259.  
  260. static int FDC1 = 0x3f0; /* Lies.  Floppy controller is memory mapped, not io mapped */
  261. static int FDC2 = -1;
  262.  
  263. #define FLOPPY0_TYPE    0
  264. #define FLOPPY1_TYPE    0
  265.  
  266. #define N_FDC 1
  267. #define N_DRIVE 8
  268.  
  269. #define EXTRA_FLOPPY_PARAMS
  270.  
  271. #endif /* __ASM_PARISC_FLOPPY_H */
  272.